<template>
    <el-dialog v-model="dialogModel" :width="dialogWidth" draggable :class="['animate__animated', dialogClass]" :before-close="onBeforeClose" :show-close="false" center :fullscreen="isFullscreen">
        <template #header="{ close, titleId }">
            <div class="dialog-header">
                <div :id="titleId" class="dialog-title">{{ dialogTitle }}</div>
                <div class="dialog-btn">
                    <el-link underline="never" @click="onFullscreen" class="fullscreen-btn">
                        <component :is="isFullscreen ? shrink() : extend()" />
                    </el-link>
                    <el-link underline="never" @click="close" class="close-btn">
                        <el-icon><Close /></el-icon>
                    </el-link>
                </div>
            </div>
        </template>
        <div :class="dialogBodyClass">
            <slot></slot>
        </div>
        <template #footer v-if="dialogFooter">
            <span class="dialog-footer">
                <slot name="frontBtn"></slot>
                <el-button type="primary" v-if="dialogShowSubmitBtn" @click="onSubmit">提交</el-button>
                <slot name="centerBtn"></slot>
                <el-button v-if="dialogShowCancelBtn" @click="onCancel">取消</el-button>
                <slot name="afterBtn"></slot>
            </span>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">
import { ref, watchEffect, onUnmounted, watch } from "vue";
import { Close } from "@element-plus/icons-vue";
import { debounce } from "lodash-es";
import { extend, shrink } from "@/utils/common";

//接收父类传过来的参数
interface Props {
    dialogTitle?: string | "";
    dialogWidth?: string | "";
    dialogFooter?: boolean;
    dialogShowSubmitBtn?: boolean;
    dialogShowCancelBtn?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
    dialogTitle: "",
    dialogWidth: "30%",
    dialogFooter: false,
    dialogShowSubmitBtn: true,
    dialogShowCancelBtn: true,
});

// 全屏状态
const isFullscreen = ref(false);

// 切换全屏
const onFullscreen = () => {
    isFullscreen.value = !isFullscreen.value;
    dialogClass.value = isFullscreen.value ? "custom-zoom-in" : "custom-zoom-out";
    // 移除动画类
    setTimeout(() => {
        dialogClass.value = "";
    }, 600);
};

//组件的双向数据绑定
const dialogModel = defineModel({ type: Boolean, default: false });

//使用defineEmits注册一个自定义事件,子传父
const emit = defineEmits(["onSubmit", "onCancel", "onBeforeClose"]);

//提交（防抖）
const onSubmit = debounce(() => emit("onSubmit"), 200);

//取消
const onCancel = () => emit("onCancel");

//关闭前触发
const onBeforeClose = () => emit("onBeforeClose");

//弹窗的class
const dialogClass = ref<string>("");

//监听弹框变化
watchEffect(() => {
    const model = dialogModel.value;
    if (!model) {
        isFullscreen.value = false;
    }
    dialogClass.value = model ? "animate__zoomIn" : "animate__zoomOut";
    setTimeout(() => {
        dialogClass.value = "";
    }, 1000);
});

const dialogBodyClass = ref<string>("");

// 监听全屏状态变化，自动处理类名
watch(isFullscreen, (newValue: boolean, _oldValue: boolean) => {
    if (newValue) {
        dialogBodyClass.value = props.dialogFooter ? "dialog-fullscreen-content-footer" : "dialog-fullscreen-content";
    } else {
        dialogBodyClass.value = "";
    }
});

//组件销毁时取消防抖
onUnmounted(() => {
    onSubmit.cancel();
});
</script>

<style scoped lang="less">
.dialog-header {
    display: flex;
    align-items: center;
    width: 100%;
    position: relative;
    .dialog-title {
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
        font-size: 16px;
        font-weight: 600;
    }
    .dialog-btn {
        margin-left: auto;
        display: flex;
        align-items: center;
        .fullscreen-btn {
            padding: 0px 5px;
            &:hover {
                color: #409eff;
            }
            :deep(.el-icon) {
                color: inherit;
            }
            :deep(svg) {
                color: inherit;
            }
            :deep(path) {
                fill: currentColor;
            }
        }
        .close-btn {
            padding: 0px 5px;
        }
    }
}
.dialog-fullscreen-content {
    :deep(> :first-child) {
        height: calc(100vh - 70px) !important;
        max-height: calc(100vh - 70px) !important;
        overflow-y: auto !important;
        .el-scrollbar__wrap {
            height: 100% !important;
            max-height: 100% !important;
        }
    }
}

.dialog-fullscreen-content-footer {
    :deep(> :first-child) {
        height: calc(100vh - 120px) !important;
        max-height: calc(100vh - 120px) !important;
        overflow-y: auto !important;
        .el-scrollbar__wrap {
            height: 100% !important;
            max-height: 100% !important;
        }
    }
}
</style>

<style>
.custom-zoom-out {
    animation: customZoomOut 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}

.custom-zoom-in {
    animation: customZoomIn 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

@keyframes customZoomOut {
    0% {
        transform: scale(1.3); /* 全屏状态 */
    }
    60% {
        transform: scale(0.95); /* 轻微过冲 */
    }
    100% {
        transform: scale(1); /* 正常状态 */
    }
}

@keyframes customZoomIn {
    0% {
        transform: scale(0.5);
    }
    50% {
        transform: scale(0.95);
    }
    100% {
        transform: scale(1);
    }
}
</style>
